userdata>config folder 10.01.23 Added .htaccess generation for current directory security 10.01.23 Added generation of agreement.txt to describe the current directory 12.06.23 Added statistics counter for visits to the current directory (using cookies) 22.07.24 Changed the script of the statistics counter for visits (introduced hashing and writing data to a separate folder) '; // Тема сторінки і відображення $options = [ // Виключаемо типи файлів, які НЕ потрібні для показу: ['.git*', '*.exe', '*.sh'] 'exclusion' => ['favicon.*', '*.php', '*.exe', '*.gz', '*.7zip', '*.dat', '*.htaccess', '*.htpasswd', '*.log', '#*', 'google*', '@*' , '*.db' , 'assets', 'error*', '*.json', 'stat*', 'index*'], // Встановлюємо ТЕМУ: 'theme' => 'dark', ]; $themes = [ 'dark' => [ 'primary' => 'rgba(19, 5, 42, 1.0)', 'secondary' => 'rgba(192, 192, 192, .75)', 'tertiary' => 'rgb(232, 232, 249)', 'banner' => 'rgba(192, 192, 192, 1.0)', ], 'night' => [ 'primary' => '#122538', 'secondary' => '#ADB5BD', 'tertiary' => '#eae3e3', 'banner' => '#DEE2E6', ], ]; // Вивід теми у змінну $theme = $themes[$options['theme']]; $style = " :root { --color-bkg: {$theme['primary']}; --color-secondary: {$theme['secondary']}; --color-tertiary: {$theme['tertiary']}; --color-banner: {$theme['banner']}; } * { box-sizing: border-box; } html { font-size: 1em; } @media (max-width: 768px) { html { font-size: 0.875em; /* Зменшення базового розміру на менших екранах */ } } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; line-height: 1.5; color: var(--color-secondary); background: var(--color-bkg); } h1, h2, h3, h4, h5, h6 { font-weight: 400; color: var(--color-banner); margin: 20px 0 10px 0; } h1 {font-size: 2.25rem; /* 36px */} h2 {font-size: 1.5rem; /* 24px */} h3 {font-size: 1.125rem; /* 18px */} h4 {font-size: 1rem; /* 16px */} h5 {font-size: 0.875rem; /* 14px */} h6 {font-size: 0.75rem; /* 12px */} table { border-spacing: 0; border-collapse: collapse; width: 100%; } caption { caption-side: top; text-align: left; } th { text-align: left; font-weight: 600; background-color: rgba(150, 212, 212, 0.1); !important; } table tr:hover td { background-color: rgba(150, 212, 212, 0.06) !important; } a { color: var(--color-tertiary); text-decoration: none; padding: 0 2px 0 2px; } a:hover { background-color: var(--color-banner); !important; color: var(--color-bkg); border-radius: 3px; padding: 1px 2px 2px 2px; } .svg_icon { fill: var(--color-tertiary); vertical-align: -0.22em; } .svg_icon:hover { fill: var(--color-bkg); vertical-align: -0.22em; } .mar10-r { margin: 0 10px 0 0; } .mar10-l { margin: 0 0 0 10px; } .mar10-t { margin: 10px 0 0 0; } .mar10-b { margin: 0 0 10px 0; } .mar20-tb { margin: 20px 0 20px 0; } .t90 { font-size: 0.9em; } .t80 { font-size: 0.875em; } .t-cener { text-align: center; } .t-color { color: var(--color-tertiary); } .height { line-height: 2.0em; } .dotted { display: flex; } .dotted:after { border-bottom: 1px dashed; content: ''; flex: 1; height: 1.1em; opacity: 0.3; } .icon { vertical-align: -0.2em; } /* STRUCTURE */ header { margin: 0 0 20px 0; } footer { margin: 20px 0 20px 0; text-align: justify; font-size: 0.875em; } blockquote { margin-left: 0; padding: 10px 0 10px 20px; border-left: 0.18em solid Gray; background-color: rgba(150, 212, 212, 0.06); border-radius: 7px; } pre { border-radius: 3px; background-color: rgba(150, 212, 212, 0.1); color: var(--color-tertiary); padding: 0 1em; overflow: auto; } code { font-family: monospace; } mark { font-family: monospace; font-size: 1em; background-color: rgba(150, 212, 212, 0.1); color: var(--color-tertiary); padding: 0.1em 0.3em; } hr { border: none; border-top: 1px dotted; height: 0; margin: 20px 0; } .wrapper { padding: 5px; max-width: 1024px; margin: auto; } .column { flex: 1; border: 1px dotted var(--color-tertiary); border-radius: 5px; margin: 2px; padding: 20px; } .columns { display: flex; flex-flow: row wrap; justify-content: center; margin: 5px 0; } .rowresize { display: grid; grid-template-columns: 1em 1fr 4em 4.5em; grid-template-rows: auto; gap: 0 10px; } /* iPad in portrait & landscape */ @media only screen and (min-device-width : 768px) and (max-device-width : 1024px) {} /* iPad in landscape */ @media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : landscape) {} /* iPad in portrait */ @media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : portrait) {} /* Retina iPad in portrait & landscape */ @media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (-webkit-min-device-pixel-ratio: 2) {} /* Retina iPad in landscape */ @media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : landscape) and (-webkit-min-device-pixel-ratio: 2) {} /* Retina iPad in portrait */ @media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : portrait) and (-webkit-min-device-pixel-ratio: 2) {} /* iPad 1 & 2 in portrait & landscape */ @media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (-webkit-min-device-pixel-ratio: 1){} /* iPad 1 & 2 in landscape */ @media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : landscape) and (-webkit-min-device-pixel-ratio: 1) {} /* iPad 1 & 2 in portrait */ @media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : portrait) and (-webkit-min-device-pixel-ratio: 1) {} /* iPad mini in portrait & landscape */ @media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (-webkit-min-device-pixel-ratio: 1) {} /* iPad mini in landscape */ @media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : landscape) and (-webkit-min-device-pixel-ratio: 1) {} /* iPad mini in portrait */ @media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : portrait) and (-webkit-min-device-pixel-ratio: 1) {} /* iPhone 5 in portrait & landscape */ @media only screen and (min-device-width : 320px) and (max-device-width : 568px) {} /* iPhone 5 in landscape */ @media only screen and (min-device-width : 320px) and (max-device-width : 568px) and (orientation : landscape) {} /* iPhone 5 in portrait */ @media only screen and (min-device-width : 320px) and (max-device-width : 568px) and (orientation : portrait) {} /* iPhone 2G-4S in portrait & landscape */ @media only screen and (min-device-width : 320px) and (max-device-width : 480px) {} /* iPhone 2G-4S in landscape */ @media only screen and (min-device-width : 320px) and (max-device-width : 480px) and (orientation : landscape) {} /* iPhone 2G-4S in portrait */ @media only screen and (min-device-width : 320px) and (max-device-width : 480px) and (orientation : portrait) {} "; // Символи SVG $icion_dir = ' '; $icion_file = ' '; $icon_up = ' UP directory '; // Фавікон для поточної сторінки $favicon = 'data:image/png;base64,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'; // Безпека по замовченню (додати при необхідності). /** $access = "./.htaccess"; // Місце для збереження файла .htaccess $put_access = '# Пріоритетні файли, які будуть відкриватися DirectoryIndex index.php index.html # Встановлення кодування за замовчуванням AddDefaultCharset UTF-8 # Встановлення заголовків для HTML файлів Header set Cache-Control "no-cache, no-store" Header unset ETag # Встановлення заголовків безпеки Header set X-Content-Type-Options "nosniff" Header set X-XSS-Protection "1; mode=block" Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" Header set Referrer-Policy "no-referrer-when-downgrade" '; if (!file_exists($access)) { file_put_contents($access, $put_access); } **/ // Ініціалізація змінних $up = ""; $project = ""; // Обмеження переходу НЕ ВИЩЕ вказаної папки (вказати назву при необхідності) // Знаходимо верхню теку if (realpath(__DIR__) == realpath($_SERVER['DOCUMENT_ROOT'])) { $up = ""; // Якщо поточна директорія є кореневою, не формуємо посилання } else { $up = "
{$icon_up}
"; // Формуємо посилання на рівень вище } // Форматуємо назву поточної папки $find = ["_", " "]; // Чистимо назву $replace = " "; $current_name = str_replace($find, $replace, mb_strtoupper(basename(__DIR__))); // Допоміжні файли assets $folderAssets = './assets/'; // Перевірка, чи папка assets вже існує if (!file_exists($folderAssets)) { // Створення папки mkdir($folderAssets, 0777, true); } $folderPic = $folderAssets.'picture/'; // Перевірка, чи папка picture вже існує if (!file_exists($folderPic)) { // Створення папки mkdir($folderPic, 0777, true); } // Опис теки (додати при необхідності). $file_agreement = $folderAssets."agreement.txt"; // Місце для збереження файла agreement.txt $put_date = 'The directory has been created: '.date('d-m-Y H:i').' [En] Stub script for folders that do not have an index file.'; $put_agreement = '

Agreement

The '.$current_name.' section is created for personal use. The scripts are written for private purposes, and the ideas are taken from open sources and reworked for the purpose of coding practice. We adhere to the CC Zero principles, which allow anyone to freely distribute, adapt, or modify materials on their own media without additional conditions. You are free to view any information and share links with others, however, please note that we reserve the right to change pages without notice.

Disclaimers

The software is provided "as is" without any warranties of any kind, either express or implied. Under no circumstances will the authors or copyright holders be liable for any damages or other claims arising from the use of the software or other actions. For correspondence and suggestions '.' '; // Для запису в файл видаляємо теги, табуляцію і додаємо перевід строки $text_agreement = strip_tags(str_replace("\t", "", $put_agreement)).$version; if (!file_exists($file_agreement)) { file_put_contents($file_agreement, $put_date.' '.$text_agreement); } // Статистика сторінки $folderStats = $folderAssets.'stats/'; // Перевірка, чи папка статистики вже існує if (!file_exists($folderStats)) { // Створення папки mkdir($folderStats, 0777, true); } // Отримання IP-адреси клієнта $ip = !empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']; // Хешування IP-адреси $hashed_ip = hash('sha256', $ip); // Отримання поточної дати та дати вчорашнього дня $today = date('d-m-Y'); $yesterday = date('d-m-Y', strtotime('-1 day')); // Визначення імен файлів $hash_db = $folderStats.'hash_db.json'; $count_db = $folderStats.'count_db.json'; // Відкриття файлу для блокування $lock_file = fopen($folderStats."lockfile.txt", "w+"); // Спроба отримати виключне блокування if(flock($lock_file, LOCK_EX)) { // Читання та декодування вмісту файлів $decodedHashJson = file_exists($hash_db) ? json_decode(file_get_contents($hash_db), true) : []; $decodedCountJson = file_exists($count_db) ? json_decode(file_get_contents($count_db), true) : []; // Ініціалізація масиву для поточного дня, якщо він не існує if (!isset($decodedHashJson[$today])) { $decodedHashJson[$today] = []; } // Якщо хеш IP-адреси не в масиві для поточного дня, додати його та збільшити лічильник if (!in_array($hashed_ip, $decodedHashJson[$today])) { $decodedHashJson[$today][] = $hashed_ip; $decodedCountJson[$today] = isset($decodedCountJson[$today]) ? $decodedCountJson[$today] + 1 : 1; $decodedCountJson["total"] = isset($decodedCountJson["total"]) ? $decodedCountJson["total"] + 1 : 1; } // Запис вмісту назад у файли file_put_contents($hash_db, json_encode($decodedHashJson, JSON_PRETTY_PRINT)); file_put_contents($count_db, json_encode($decodedCountJson, JSON_PRETTY_PRINT)); // Визначення дня з максимальною кількістю відвідувачів $max_visitors = 0; $max_day = ""; foreach($decodedCountJson as $day => $visitors) { if($day == "total") continue; if($visitors > $max_visitors) { $max_visitors = $visitors; $max_day = $day; } } // Зняття блокування flock($lock_file, LOCK_UN); } // Закриття файлу блокування fclose($lock_file); // Інформація про версію РНР if(!empty($_GET['phpinfo'])) { phpinfo(); exit; } // Інформація про сервер $host_version = $_SERVER['SERVER_NAME']; $apache_version = explode(' ', explode('/', $_SERVER['SERVER_SOFTWARE'])[1])[0]; $php_version = explode('-', phpversion())[0]; $mysql_version = explode('-', explode(' ', mysqli_get_client_info())[1])[0]; // Інформація про сертифікат SSL $url_ssl = 'ssl://' . $host_version . ':443'; $context = stream_context_create(array( 'ssl' => array( 'capture_peer_cert' => true, 'verify_peer' => false, // так як проміжний сертифікат може бути відсутній, 'verify_peer_name' => false // то вимикаємо його перевірку. ) )); $fp = stream_socket_client($url_ssl, $err_no, $err_str, 30, STREAM_CLIENT_CONNECT, $context); $cert = stream_context_get_params($fp); if (empty($err_no)) { $ssl = openssl_x509_parse($cert['options']['ssl']['peer_certificate']); $ssl_center = $ssl['issuer']['CN']; $ssl_date = date('d.m.Y', $ssl['validTo_time_t']); } if ($apache_version == "" or $mysql_version == ""){ $server = [ // На випадок, якщо в налаштуваннях серверу Apache у файлі httpd.conf не встановлений параметр: ServerTokens Minimal 'Host' => $host_version, 'SSL to' => $ssl_date, // Дія сертифікату SSL 'Software' => $_SERVER['SERVER_SOFTWARE'], 'Time zone' => date_default_timezone_get(), 'Protocol' => $_SERVER['SERVER_PROTOCOL'] ];} else { $server = [ 'Host' => $host_version, 'SSL to' => $ssl_date, // Дія сертифікату SSL 'Apache' => $apache_version, 'PHP' => $php_version, 'MySQL' => $mysql_version, ];} // Розмір теки з вкладеними файлами function folderSize ($dir) { $size = 0; foreach (glob(rtrim($dir, '/').'/*', GLOB_NOSORT) as $each) { $size += is_file($each) ? filesize($each) : folderSize($each); } return sizeFilter($size); } // Розмірність в байтах function sizeFilter($bytes) { $label = array('B', 'KB', 'MB', 'GB', 'TB', 'PB'); for ($i = 0; $bytes >= 1024 && $i < (count($label) - 1); $bytes /= 1024, $i++); return (round($bytes, 2) . " " . $label[$i]); } // Перевірка імені файлу по масиву шаблонів виключень function filenameMatch($patternArray, $filename) { if (empty($patternArray)) { return false; } foreach ($patternArray as $pattern) { if (fnmatch($pattern, $filename)) { return true; } } return false; } // Перебір всіх елементів у поточній папці $directory_list = []; if($handle = opendir('./')) { $item_list = []; while(false !== ($item = readdir($handle))) { if($item == '..' || $item == '.' || filenameMatch($options['exclusion'], $item)) { continue; } $item_type = is_dir($item) ? 'dir' : 'file'; $order = ($item_type == 'dir') ? 1 : 0; $item_list[] = [ 'name' => $item, 'type' => $item_type, 'order' => $order ]; } $order_column = array_column($item_list, 'order'); array_multisort($order_column, SORT_DESC, $item_list); $directory_list = $item_list; closedir($handle); } // Ініціалізація змінних $dir_list = ''; $file_list = ''; // Формування списку файлів і папок foreach ($directory_list as $item) { $items = $item['name']; $string = str_replace($find, $replace, $items); if ($item['type'] == 'dir') { // Формуємо список папок $string = strtoupper($string); $folderSize = '― dir ―'; // $folderSize = folderSize($items); // Якщо потрібен розмір папки, розкоментуйте цей рядок if (is_dir($items)) { $dir = '
' . $icion_dir . '
' . htmlspecialchars($string) . '  
' . date("d-m-y", filectime($items)) . '
'.$folderSize.'
'; $dir_list = $dir_list . $dir; } } if ($item['type'] == 'file') { // Формуємо список файлів $string = strtolower($string); if (pathinfo($string)['extension'] == 'html'){ // Якщо потрібне розширення, закоментуйте умову $string = pathinfo($string)['filename']; } if (is_file($items)) { $fileSize = sizeFilter(filesize($items)); $file = '
' . $icion_file . '
' . htmlspecialchars($string) . '  
' . date("d-m-y", filectime($items)) . '
' . $fileSize . '
'; $file_list = $file_list . $file; } } } $file_List = $dir_list . $file_list; // Скорочені дані про браузер $browser = get_browser_name($_SERVER['HTTP_USER_AGENT']); function get_browser_name($user_agent) { // Робимо пошук нечутливим до регістру $t = strtolower($user_agent); // Визначаємо патерни для різних браузерів та ботів $browsers = [ 'opera' => 'Opera', 'opr/' => 'Opera', 'edge' => 'Edge', 'chrome' => 'Chrome', 'safari' => 'Safari', 'firefox' => 'Firefox', 'msie' => 'Internet Explorer', 'trident/7' => 'Internet Explorer', 'google' => '[Bot] Googlebot', 'bing' => '[Bot] Bingbot', 'slurp' => '[Bot] Yahoo! Slurp', 'duckduckgo'=> '[Bot] DuckDuckBot', 'baidu' => '[Bot] Baidu', 'yandex' => '[Bot] Yandex', 'sogou' => '[Bot] Sogou', 'exabot' => '[Bot] Exabot', 'msn' => '[Bot] MSN', 'mj12bot' => '[Bot] Majestic', 'ahrefs' => '[Bot] Ahrefs', 'semrush' => '[Bot] SEMRush', 'rogerbot' => '[Bot] Moz or OpenSiteExplorer', 'dotbot' => '[Bot] Moz or OpenSiteExplorer', 'frog' => '[Bot] Screaming Frog', 'screaming' => '[Bot] Screaming Frog', 'facebook' => '[Bot] Facebook', 'pinterest' => '[Bot] Pinterest', ]; foreach ($browsers as $key => $value) { if (stripos($t, $key) !== false) { return $value; } } // Перевірка на наявність рядків, які використовуються в агентах користувачів ботів $bot_indicators = ['crawler', 'api', 'spider', 'http', 'bot', 'archive', 'info', 'data']; foreach ($bot_indicators as $indicator) { if (stripos($t, $indicator) !== false) { return '[Bot] Other'; } } return 'Other (UNKNOWN)'; } // Скорочені дані про юзера, отримані через IP function get_ip() { $ip_keys = [ 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR' ]; foreach ($ip_keys as $key) { if (!empty($_SERVER[$key])) { // Якщо це 'HTTP_X_FORWARDED_FOR', обробляємо кілька IP-адрес if ($key === 'HTTP_X_FORWARDED_FOR') { $ips = explode(',', $_SERVER[$key]); foreach ($ips as $ip) { $ip = trim($ip); // Видаляємо пробіли if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { // Перевіряємо, чи не є це IP-адреса localhost if ($ip !== '127.0.0.1') { return $ip; } } } } else { if (filter_var($_SERVER[$key], FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { // Перевіряємо, чи не є це IP-адреса localhost if ($_SERVER[$key] !== '127.0.0.1') { return $_SERVER[$key]; } } } } } return '127.0.0.1'; // Повертаємо localhost, якщо жоден інший IP не знайдено } $ip = get_ip(); // IP-адреса // Ініціалізуємо cURL-ресурс $ch = curl_init(); // Встановлюємо URL-адресу для запиту curl_setopt($ch, CURLOPT_URL, "http://www.geoplugin.net/json.gp?ip=".$ip); // Повертати результат, а не виводити його в браузер curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Виконуємо запит $file = curl_exec($ch); // Перевіряємо наявність помилки під час виконання запиту if ($file === false) { echo 'Помилка отримання даних geoplugin.net!'; exit; } // Декодуємо отриманий JSON $ipdat = json_decode($file); // Перевіряємо наявність помилки при декодуванні JSON if (!$ipdat) { echo 'Помилка декодування даних geoplugin.net!'; exit; } // Закриваємо cURL-ресурс curl_close($ch); // Отримані дані доступні в змінній $ipdat // На випадок, якщо у виводі не потрібен параметр, його можна закоментувать $user = [ 'Addr IP' => $ip, 'Continent' => $ipdat->geoplugin_continentName, 'Country' => $ipdat->geoplugin_countryName, 'City' => $ipdat->geoplugin_city, // 'Lat' => $ipdat->geoplugin_latitude, // 'Long' => $ipdat->geoplugin_longitude, // 'Сurrency symbol' => $ipdat->geoplugin_currencySymbol, // 'Currency code' => $ipdat->geoplugin_currencyCode, 'Time zone' => $ipdat->geoplugin_timezone, 'Browser' => $browser ]; // Формування таблиці PAGE INFO if ($decodedCountJson[$yesterday] == '') {$decodedCountJson[$yesterday] = 'none';} $info = ' Total visits'.$decodedCountJson["total"].' Today\'s visitors'.$decodedCountJson[$today].' Yesterday\'s visitors'.$decodedCountJson[$yesterday].' '; // Змінна для виводу $stat_info = ''.$info.'
With '.$max_visitors.' visitors, '.$max_day.' was the day with most traffic.
'; // Формування таблиці USER INFO $info = $td = $label = $value = ""; // Чистимо сміття у змінних foreach($user as $label => $value){ if (!empty($value)){ $td = ''.$label.''.$value.''; $info = $info.''.$td.''; } } // Змінна для виводу $user_info = ''.$info.'
'; // Формування таблиці SERVER INFO $info = $td = $label = $value = ""; // Чистимо сміття у змінних foreach($server as $label => $value){ if (!empty($value)){ $td = ''.$label.''.$value.''; $info = $info.''.$td.''; } } // Змінна для виводу $server_info = ''.$info.'
'; ?> <?= $current_name ?>

The table shows a list of directories and files available for viewing in this scenario, directory caching is not used, so the list is generated on the fly. The required level of protection is provided by the configuration of the .htaccess file.

Page info

User info

Server info